package com.report.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zhxu.bs.BeanSearcher;
import cn.zhxu.bs.SearchResult;
import cn.zhxu.bs.operator.*;
import cn.zhxu.bs.util.MapBuilder;
import cn.zhxu.bs.util.MapUtils;
import com.report.dto.request.*;
import com.report.dto.response.ImageInfoRes;
import com.report.dto.response.ReportRes;
import com.report.dto.response.SubjectRes;
import com.report.dto.response.TodaySellRes;
import com.report.dto.response.zu.WeChatMiniReportRes;
import com.report.entity.DownloadReport;
import com.report.entity.PDFImage;
import com.report.entity.Report;
import com.report.mapper.FileMapper;
import com.report.mapper.ReportMapper;
import com.report.pdf.PdfUtils;
import com.report.service.DownloadReportService;
import com.report.service.ICollectService;
import com.report.service.IReportService;
import com.report.service.PDFImageService;
import com.report.utils.DownloadFileUtils;
import com.zmh.framework.constants.Constants;
import com.zmh.framework.oss.OssConfigure;
import com.zmh.framework.util.Base64ToMultipartFile;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author summer
 * @since 2024/06/25 14:54:53
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements IReportService {

    private final BeanSearcher beanSearcher;

    @Override
    public Page<ReportRes> lists(ReportReq reportReq) {
        Page<ReportRes> page = new Page<>(reportReq.getPageNum(), reportReq.getPageSize());
        Map<String, Object> build = MapUtils.builder().page(reportReq.getPageNum() - 1, reportReq.getPageSize())
                .field(ReportReq::getName, reportReq.getName()).op(Contain.class)
                .field(ReportReq::getAuth, reportReq.getAuth()).op(Contain.class)
                .field(ReportReq::getTypeId, reportReq.getTypeId()).op(Equal.class)
                .field(ReportRes::getDeleted, Constants.ZERO).op(Equal.class)
                .field(ReportRes::getRecentId,reportReq.getRecentId()).op(Equal.class)
                .field(ReportRes::getTodaySell,reportReq.getTodaySell()).op(Equal.class)
                .field(ReportRes::getRanking,reportReq.getRanking()).op(Equal.class)
                .field(ReportReq::getSecurityId, reportReq.getSecurityId()).op(Equal.class)
                .field(ReportReq::getIndustryId, reportReq.getIndustryId()).op(Equal.class).build();
        SearchResult<ReportRes> search = beanSearcher.search(ReportRes.class, build);
        page.setTotal(search.getTotalCount().longValue());
        page.setRecords(search.getDataList());
        return page;
    }




    @Override
    public List<TodaySellRes> todayRecommendList() {
        Page<Report> page = this.page(new Page<>(1, 10), getLambdaQuery().eq(Report::getTodaySell, 1).orderByDesc(Report::getCreateTime));
       return Convert.toList(TodaySellRes.class, page.getRecords()) ;
    }

    public LambdaQueryWrapper<Report>  getLambdaQuery(){
        return Wrappers.lambdaQuery(Report.class);
    }


    @Override
    public List<TodaySellRes> rankingList() {
        LambdaQueryWrapper<Report> eq = Wrappers.lambdaQuery(Report.class).eq(Report::getRanking, 1).orderByDesc(Report::getCreateTime);
        Page<Report> page = this.page(new Page<>(1, 10), eq);
        return Convert.toList(TodaySellRes.class, page.getRecords()) ;
    }

    @Override
    public Page<TodaySellRes> recentList(RecentReq recentReq) {
        Page<Report> page = this.page(new Page<>(recentReq.getPageNum(), recentReq.getPageSize()), Wrappers.lambdaQuery(Report.class).eq(Report::getRecentId, recentReq.getRecentId()).orderByDesc(Report::getCreateTime));
        return Convert.convert(new TypeReference<Page<TodaySellRes>>() {
        }, page);
    }

    private final PDFImageService pdfImageService;

    @Override
    public ReportRes findById(Integer id) {
        Report report = this.getById(id);
        if(ObjectUtil.isNotEmpty(report)){
            report.setBrowseNum(report.getBrowseNum()+1);
            this.updateById(report);
        }
        Map<String, Object> build = MapUtils.builder().field(ReportRes::getId, id).op(Equal.class).build();
        return beanSearcher.searchFirst(ReportRes.class, build);
    }


    @Override
    public Page<PDFImage> findPDFImage(ReportFileReq fileReq) {
        LambdaQueryWrapper<PDFImage> eq = Wrappers.lambdaQuery(PDFImage.class).eq(PDFImage::getPdfId, fileReq.getId());
        long count = pdfImageService.count(eq);
        if(count == 0){

        }
        Page<PDFImage> page = new Page<>(fileReq.getPageNum(), fileReq.getPageSize());
         return pdfImageService.page(page, eq);
    }

    private final FileMapper fileMapper;



    private final DownloadReportService downloadReportService;

    private final DownloadFileUtils downloadFileUtils;

    @Override
    public void downloadReportFile(Integer id, HttpServletResponse response) {
        LambdaQueryWrapper<DownloadReport> eq = Wrappers.lambdaQuery(DownloadReport.class).eq(DownloadReport::getReportId, id)
                .eq(DownloadReport::getMemberId, StpUtil.getLoginId());
        DownloadReport one = downloadReportService.getOne(eq);
        if(ObjectUtil.isEmpty(one)){
            DownloadReport downloadReport = new DownloadReport();
            downloadReport.setReportId(id);
            downloadReport.setMemberId(Convert.convert(Integer.class, StpUtil.getLoginId()));
            downloadReportService.save(downloadReport);
        }

    }

    private final OssConfigure ossConfigure;

    @Override
    public void saveReport(ReportReq reportReq) {
        if(reportReq.getShowImage()){
            MultipartFile multipartFile = Base64ToMultipartFile.base64ToMultipart(reportReq.getImage());
            String image = ossConfigure.uploadFile(multipartFile);
            reportReq.setImage(image);
        }
        this.saveOrUpdate(Convert.convert(Report.class, reportReq));
    }

    @Override
    public Page<ImageInfoRes> imageLists(FileReq fileReq) {
        Page<ImageInfoRes> page=new Page<>(fileReq.getPageNum(),fileReq.getPageSize());
        Map<String, Object> build = MapUtils.builder().page(fileReq.getPageNum()-1, fileReq.getPageSize())
                .field(ImageInfoRes::getIndustryId,fileReq.getIndustryId()).op(Equal.class)
                .field(ImageInfoRes::getName,fileReq.getName()).op(Contain.class)
                .field(ImageInfoRes::getDeleted,Constants.ZERO).op(Equal.class).build();
        SearchResult<ImageInfoRes> search = beanSearcher.search(ImageInfoRes.class, build);
        page.setTotal(search.getTotalCount().longValue());
        page.setRecords(search.getDataList());
        return page;
    }

    @Override
    public List<ReportRes> finBreStateReport() {
        LambdaQueryWrapper<Report> eq = Wrappers.lambdaQuery(Report.class).select(Report::getId,Report::getName)
                .orderByDesc(Report::getCreateTime);
        return Convert.toList(ReportRes.class,this.list(eq));
    }


    @Override
    public Page<ReportRes> newReportList(ReportReq reportReq) {
        Page<Report> page=new Page<>(reportReq.getPageNum(), reportReq.getPageSize());
        LambdaQueryWrapper<Report> reportLambdaQueryWrapper = Wrappers.lambdaQuery(Report.class).orderByDesc(Report::getCreateTime);
        page = this.page(page,reportLambdaQueryWrapper);
        return Convert.convert(new TypeReference<Page<ReportRes>>() {
        },page);
    }

    private final ICollectService collectService;

    private MapBuilder getMapBuilder(Integer pageNum, Integer pageSize) {
        return MapUtils.builder().page(pageNum - 1, pageSize);

    }

    @Override
    public Page<WeChatMiniReportRes> wechatReportList(WeChatMiniReportReq reportReq) {
        Page<WeChatMiniReportRes> page=new Page<>(reportReq.getPageNum(), reportReq.getPageSize());
        page=this.baseMapper.wechatReportList(page,reportReq);
        return page;
    }

    @Override
    public void saveRecommend(RecommendReq recommendReq) {
        Report report = this.getById(recommendReq.getId());
        if(recommendReq.getIsSelected()){
            report.setBrowseNum(report.getBrowseNum()+1);
        }else{
            report.setBrowseNum(report.getBrowseNum()-1);

        }
        this.updateById(report);
    }



    @Override
    public ReportRes sendPoster(Integer reportId) {
            Map<String, Object> build = MapUtils.builder().field(ReportRes::getId, reportId).build();
           return beanSearcher.searchFirst(ReportRes.class, build);
    }

    @Override
    public Page<SubjectRes> findReportList(SpecialReq req) {
        Map<String, Object> build = MapUtils.builder().page(req.getPageNum() - 1, req.getPageSize())
                .field(SubjectRes::getSpecialId, req.getSubjectId()).op(Equal.class)
                .build();
        SearchResult<SubjectRes> search = beanSearcher.search(SubjectRes.class, build);
        Page<SubjectRes> page=new Page<>(req.getPageNum(), req.getPageSize());
        page.setTotal(search.getTotalCount().longValue());
        page.setRecords(search.getDataList());
        return page;
    }
}
